package org.bigk.invoices.services;

import java.util.List;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.bigk.invoices.exceptions.ServiceException;
import org.bigk.invoices.model.Purchaser;
import org.bigk.invoices.model.PurchaserFilter;
import org.bigk.invoices.utils.HibernateUtils;
import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;

public class PurchasersServiceImpl implements PurchasersService {
	
	/**
	 * Logger for this class
	 */
	private static final Log logger =
		LogFactory.getLog(PurchasersServiceImpl.class);

	public PurchasersServiceImpl() {
	}

	@SuppressWarnings("unchecked")
	public List<Purchaser> listAllItems() throws ServiceException {
		
		if (logger.isDebugEnabled()) {
			logger.debug("listAllItems() - start");
		}

		List<Purchaser> list = null;
		Session session = null;
		try {
			session = HibernateUtils.getCurrentSession();
			
			Criteria crit = session.createCriteria(Purchaser.class);
			crit.addOrder(Order.asc("id"));
			
			list = crit.list();
			
		} catch (HibernateException ex) {
			logger.error("listAllItems()", ex);
			throw new ServiceException(ex);
		}

		if (logger.isDebugEnabled()) {
			logger.debug("listAllItems() - end - return value=" + CollectionUtils.size(list));
		}
		return list;		
	}

	@SuppressWarnings("unchecked")
	public List<Purchaser> listItems4Page(PurchaserFilter filter) throws ServiceException {
		if (logger.isDebugEnabled()) {
			logger.debug("listItems4Page(PurchaserFilter filter=" + filter + ") - start");
		}

		List<Purchaser> list = null;
		Session session = null;
		try {
			session = HibernateUtils.getCurrentSession();
			
			Criteria crit = session.createCriteria(Purchaser.class);
			crit.addOrder(Order.asc("id"));
			
			if (filter != null) {
				if (filter.getId() != null)
					crit.add(Restrictions.idEq(filter.getId()));
				
				if (StringUtils.isNotEmpty(filter.getName()))
					crit.add(Restrictions.like("name", filter.getName(), MatchMode.ANYWHERE));
				
				if (StringUtils.isNotEmpty(filter.getNip()))
					crit.add(Restrictions.eq("nip", filter.getNip()));
			}
			HibernateUtils.updateStats(crit, filter);
			int firstResult = (filter.getCurrentPage().intValue() - 1)
					* filter.getPaginatedPageSize().intValue();
			int maxResults = filter.getPaginatedPageSize().intValue();
			crit.setFirstResult(firstResult);
			crit.setMaxResults(maxResults);
			list = crit.list();
		} catch (HibernateException ex) {
			logger.error("listItems4Page(PurchaserFilter)", ex);
			throw new ServiceException(ex);
		}

		if (logger.isDebugEnabled()) {
			logger.debug("listItems4Page(PurchaserFilter) - end - return value=" + CollectionUtils.size(list));
		}
		return list;
	}

	public Purchaser getPurchaser(Long id) throws ServiceException {
		if (logger.isDebugEnabled()) {
			logger.debug("getPurchaser(Long id=" + id + ") - start");
		}

		Purchaser object = null;
		Session session = null;
		try {
			session = HibernateUtils.getCurrentSession();
			object = (Purchaser) session.get(Purchaser.class, id);
		} catch (HibernateException ex) {
			logger.error("getPurchaser(Long)", ex);
			throw new ServiceException(ex);
		}

		if (logger.isDebugEnabled()) {
			logger.debug("getPurchaser(Long) - end - return value=" + object);
		}
		return object;
	}
	
	public void savePurchaser(Purchaser purchaser) throws ServiceException {
		if (logger.isDebugEnabled()) {
			logger.debug("savePurchaser(Purchaser purchaser=" + purchaser + ") - start");
		}

		Session session = null;
		try {
			session = HibernateUtils.getCurrentSession();
			session.save(purchaser);
		} catch (HibernateException ex) {
			logger.error("savePurchaser(Purchaser)", ex);
			throw new ServiceException(ex);
		}

		if (logger.isDebugEnabled()) {
			logger.debug("savePurchaser(Purchaser) - end");
		}
	}
	
	public void updatePurchaser(Purchaser purchaser) throws ServiceException {
		if (logger.isDebugEnabled()) {
			logger.debug("updatePurchaser(Purchaser purchaser=" + purchaser + ") - start");
		}

		Session session = null;
		try {
			session = HibernateUtils.getCurrentSession();
			session.update(purchaser);
		} catch (HibernateException ex) {
			logger.error("updatePurchaser(Purchaser)", ex);
			throw new ServiceException(ex);
		}

		if (logger.isDebugEnabled()) {
			logger.debug("updatePurchaser(Purchaser) - end");
		}
	}

	public void deletePurchaser(Purchaser purchaser) throws ServiceException {
		if (logger.isDebugEnabled()) {
			logger.debug("deletePurchaser(Purchaser purchaser=" + purchaser + ") - start");
		}

		Session session = null;
		try {
			session = HibernateUtils.getCurrentSession();
			session.delete(purchaser);
		} catch (HibernateException ex) {
			logger.error("deletePurchaser(Purchaser)", ex);
			throw new ServiceException(ex);
		}

		if (logger.isDebugEnabled()) {
			logger.debug("deletePurchaser(Purchaser) - end");
		}
	}

}
